package com.geekchique.runningbuddy.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.geekchique.runningbuddy.model.Jog;
import com.geekchique.runningbuddy.model.ListOfJogs;
import com.geekchique.runningbuddy.provider.ActivityID;
import com.geekchique.runningbuddy.util.LocationUtils;

import android.location.Location;
import android.os.Handler;
import android.os.Message;
import android.content.Context;

import android.util.Log;

/******************************************************************************
* This class contains methods related to the canned jogs functionality, 
* used for testing.
*/ 
public class CannedRunManagerImpl implements ICannedRunManager { //For Shoehorn 158

	private double runSpeed;
	private int runId;
    private ListOfJogs cannedJogs;
    private double distance; //distance jogged in meters
    private final int simTickTime = 4000; //update period in ms
	private static final String TAG = "[RBuddy]: " + CannedRunManagerImpl.class.getName();
	private boolean runSimLocationThread;
	private Thread locationSimThread = null;

	public CannedRunManagerImpl(Context context)
	{
        cannedJogs = readCannedJogs(context);
        
        distance = 0.0;
        runId = 0;
        runSpeed = 6.0;
	}
	
	public int getRunId() {
		return runId;
	}

	public double getSpeed() {
		return runSpeed;
	}

	public void setRunId(int id) {
		runId = id;
	}

	public void setSpeed(double speed) {
		runSpeed = speed;
	}

	private Handler messageHandler;
	
	public void startRun(Handler msgHandler) {
		messageHandler = msgHandler;
		distance = 0.0;
		runSimLocationThread=true;
		locationSimThread= new Thread()
		{
			public void run()
			{
				while (runSimLocationThread)
				{
					try {
						updateSimLocation();
						sleep(simTickTime);
					}
					catch (InterruptedException e)
					{
						//don't care
					}
				}
			}
		};
		
		locationSimThread.start();

	}

	public void stopRun() {
		runSimLocationThread = false;
		locationSimThread.interrupt();
		locationSimThread = null;
	}

	
	
	private int cannedPointId = 0;
	private void updateSimLocation()
	{
		Jog currentJog = cannedJogs.get(runId);
		
		Location newLoc = LocationUtils.getJogLocationFromDistance(currentJog, distance);
		newLoc.setTime(System.currentTimeMillis());
		
		distance = distance + runSpeed * simTickTime / 1000;
		
		if (newLoc!=null)
		{
			Message msg = Message.obtain(messageHandler, ActivityID.LOCATION_UPDATE, newLoc);
			messageHandler.sendMessageDelayed(msg, 50);
		}
		else
		{
			Log.w(TAG, "Null location for canned pid " + cannedPointId);
		}
		
		cannedPointId++;
	}


	
	public static ListOfJogs readCannedJogs(Context ctxt)
	{
		ListOfJogs jogList = new ListOfJogs();
		
		InputStream inStream = ctxt.getResources().openRawResource(com.geekchique.runningbuddy.R.raw.canned_routes);
		BufferedReader in
		   = new BufferedReader(new InputStreamReader(inStream));


		try {
			String line = in.readLine();
			
			Jog newJog = null;
			
			while (line != null)
			{
				int bPos = line.indexOf('[');
				if (bPos>0)
				{
					String routeName = line.substring(0, bPos);
					int ptId = Integer.parseInt(line.substring(bPos+1, line.indexOf(']')));
					line = line.substring(line.indexOf(']') + 2);
					double longitude = Double.parseDouble(line.substring(0, line.indexOf(' ')));
					line = line.substring(line.indexOf(' ') + 1);
					double latitude = Double.parseDouble(line);
					
					if ((newJog==null) || (newJog.getName().compareTo(routeName)!=0))
					{
						if (newJog != null)
						{
							jogList.add(newJog);
						}
						newJog = new Jog(routeName, 0, 0);
					}
					Location newLoc = new Location();
					newLoc.setLatitude(latitude);
					newLoc.setLongitude(longitude);
					newLoc.setTime(ptId); //This just needs to be unique, time is not used for canned routes
					newJog.addRoutePoint(newLoc);		
					
				}
				line = in.readLine();

			}
			if (newJog != null)
			{
				jogList.add(newJog);
			}
		} 
		catch (IOException e) {
		}
		
		return jogList;
	}

	
}
